﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Styx;
using Styx.CommonBot;
using Styx.Plugins;
using Styx.Common;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using System.Windows.Media;
using System.IO;
using System.Threading;
using System.Diagnostics;

namespace Blacklister
{
    public class BlacklisterPlugin : HBPlugin
    {
        public override string Author { get { return "Kamilche"; } }
        public override Version Version { get { return new Version(1, 0, 0); } }
        public override string Name { get { return "Blacklister"; } }
        public override bool WantButton { get { return true; } }
        public override string ButtonText { get { return "Settings..."; } }
        private static Form1 form = null;
        private static WoWPoint lastnode = WoWPoint.Empty;
        public static int mindistance = 20;
        public static int maxmobs = 0;
        public static string textholder = "";
        public static string txtMobList = "";
        public static HashSet<String> hashMobs = new HashSet<String>();
        private static string[] validbots = { "Combat Bot", "Gatherbuddy2", "Questing", "Grind Bot","ProfessionBuddy" };
        private static string _datapath = Path.Combine(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), "Plugins\\Blacklister\\users");
        private static string _savepath = Path.Combine(Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName), "Plugins\\Blacklister");
        public static double secs = 120;
        private bool firstTime = true;

        public override void OnButtonPress()
        {
            form = new Form1();
            form.Show();
        }

        public override void Pulse()
        {
            if (firstTime == true)
            {
                firstTime = false;
                load();
            }
            if (!validbots.Contains(Styx.CommonBot.BotManager.Current.Name))
            {
                Logging.Write(Colors.Red, "Invalid bot type {0}", Styx.CommonBot.BotManager.Current.Name);
                return;
            }
            if (!(StyxWoW.IsInGame &&
                  StyxWoW.Me != null &&
                  StyxWoW.Me.IsValid &&
                 !StyxWoW.Me.IsDead &&
                 !StyxWoW.Me.IsGhost))
            {
                Logging.Write(Colors.Red, "Invalid state");
                return;
            }

            List<WoWGameObject> node = (from o in ObjectManager.GetObjectsOfType<WoWGameObject>(false, false)
                                        where (o.IsHerb || o.IsMineral)
                                        where !Blacklist.Contains(o.Guid, BlacklistFlags.Node)
                                        where (o.IsHerb && o.RequiredSkill <= StyxWoW.Me.GetSkill(Styx.SkillLine.Herbalism).CurrentValue) ||
                                              (o.IsMineral && o.RequiredSkill <= StyxWoW.Me.GetSkill(Styx.SkillLine.Mining).CurrentValue)
                                        orderby o.DistanceSqr ascending
                                        select o).ToList();

            List<WoWUnit> allunits = (
                from u in ObjectManager.GetObjectsOfType<WoWUnit>(false, false)
                where u.IsHostile  || hashMobs.Contains(u.Name)
                where u.CanSelect && u.Attackable
                where !u.IsDead
                select u).ToList();

            for (int i = 0; i < node.Count; i++)
            {
                List<WoWUnit> closemobs = (
                    from u in allunits
                    where u.Location.DistanceSqr(node[i].Location) < mindistance * mindistance
                    orderby u.Location.DistanceSqr(node[i].Location)
                    select u).ToList();

                if (closemobs.Count <= maxmobs)
                {
                    string mobtag = "";
                    if (closemobs.Count > 0)
                        mobtag = string.Format("(closest mob {0} at {1:0.00}", closemobs[0].Name, allunits[0].Location.Distance(node[i].Location));
                    Logging.WriteDiagnostic(Colors.Yellow, "Node {0} {1} at {2:0.00} yards ({3}) {4}", i, node[i].Name, StyxWoW.Me.Location.Distance(node[i].Location), node[i].Location.ToString(), mobtag);
                }
                else
                {
                    Logging.Write(Colors.Orange, "Blacklisting {0} for {1} seconds because there's {2} mobs within {3} yards (closest {4} at {5}).", 
                        node[i].Name, secs, closemobs.Count, mindistance, closemobs[0].Name, closemobs[0].Location.Distance(node[i].Location));
                    Blacklist.Add(node[i].Guid, BlacklistFlags.Node, TimeSpan.FromSeconds(secs));
                }
            }
        }

        public static void save()
        {
            string filenametemp = String.Format("{0}\\{1}.txt", _datapath, StyxWoW.Me.Name);
            List<string> lst = new List<string>();
            lst.Add(String.Format("maxRange\t{0}", mindistance));
            lst.Add(String.Format("maxMobs\t{0}", maxmobs));
            lst.Add(String.Format("blacklistTime\t{0}", secs));
            System.IO.File.WriteAllLines(filenametemp, lst);
        }

        public static void saveList()
        {
            string filenametemp = String.Format("{0}\\{1}.txt", _savepath, "Moblist");
            System.IO.File.WriteAllText(filenametemp, textholder);
            save();
            txtMobList = "";
            load();
        }

        private static HashSet<String> LoadList(String filename)
        {
            HashSet<String> h = new HashSet<String>();
            string[] lines = File.ReadAllLines(filename);
            foreach (String line in lines)
            {
                String s = line.Trim();
                if (s.Length == 0 || s.StartsWith("//") || s.StartsWith("--"))
                    continue;

                if (!h.Contains(s))
                {
                    h.Add(s);
                }
            }
            return h;
        }

        public static void load()
        {
            string filename = String.Format("{0}\\{1}.txt", _datapath, StyxWoW.Me.Name);
            string mobFilename = String.Format("{0}\\{1}.txt", _savepath, "Moblist");
            txtMobList = "";
            hashMobs = LoadList(mobFilename);
           
            if (!System.IO.File.Exists(filename))
            {
                save();
            }

            List<string> lst = new List<string>();
            lst = new List<string>(System.IO.File.ReadAllLines(filename));

            for (int i = 0; i < lst.Count; i++)
            {
                string line = lst[i];
                string[] words = line.Split('\t');

                if (words[0] == "maxRange")
                {
                    int value = Int32.Parse(words[1]);
                    mindistance = value;
                }

                if (words[0] == "maxMobs")
                {
                    int value = Int32.Parse(words[1]);
                    maxmobs = value;
                }

                if (words[0] == "blacklistTime")
                {
                    Double value = Double.Parse(words[1]);
                    secs = value;
                }
            }

            string[] mobLines = File.ReadAllLines(mobFilename);
            Array.Sort(mobLines);
            List<string> checkedmobLines = new List<string>();
  //             List<string> vals = new List<string>();
  //bool returnValue = false;
  // foreach(string s in arrayList)
  // {
  //    if(vals.Contains(s))
  //    {
  //        returnValue = true;
  //        break;
  //    }
  //    vals.Add(s);

            foreach (string s in mobLines)
            {
                if(checkedmobLines.Contains(s))
                {
                    continue;
                }
                checkedmobLines.Add(s);
            }

            

            for (int y = 0; y < checkedmobLines.ToArray().Length; y++)
            {
                txtMobList += checkedmobLines.ToArray()[y] + "\r\n";
            }



        }

    }
}
